package com.corn.turorial.spring.config;

import com.corn.turorial.spring.converter.MyMapHttpMessageConverter;
import com.corn.turorial.spring.exception.MyCustomerHandlerExceptionResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.accept.ContentNegotiationStrategy;
import org.springframework.web.accept.HeaderContentNegotiationStrategy;
import org.springframework.web.accept.ParameterContentNegotiationStrategy;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author : Jim Wu
 * @version 1.0
 * @function :
 * @since : 2021/2/4 17:47
 */

@Configuration
public class MyWebConfiguration implements WebMvcConfigurer {

    /**
     * 添加自己的messageConverter
     *
     * @param converters
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MyMapHttpMessageConverter());
    }

    /**
     * 注意覆盖这个方法之后 默认HeaderContentNegotiationStrategy为被覆盖
     *
     * @param configurer
     */
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        List<ContentNegotiationStrategy> strategies = new ArrayList<>();
        Map<String, MediaType> mediaTypes = new HashMap<>();
        mediaTypes.put("json", MediaType.APPLICATION_JSON);
        mediaTypes.put("xml", MediaType.APPLICATION_XML);
        mediaTypes.put("myContentType", MediaType.parseMediaType("application/myContentType"));
        // ParameterContentNegotiationStrategy 构造器可以传入map 添加自定义的MediaType和format参数值的映射关系
        ParameterContentNegotiationStrategy parameterStrategy = new ParameterContentNegotiationStrategy(mediaTypes);
        // 为了避免与前端传入的参数名重复还可以自定义参数名
        parameterStrategy.setParameterName("myFormat");
        strategies.add(parameterStrategy);
        strategies.add(new HeaderContentNegotiationStrategy());
        configurer.strategies(strategies);
    }


    /**
     * 扩展自己的resolver
     *
     * @param resolvers
     */
    @Override
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        resolvers.add(0, new MyCustomerHandlerExceptionResolver());
    }

    @Autowired
    private LocaleChangeInterceptor localeChangeInterceptor;

    /**
     * register locale change interceptor.
     *
     * @param registry registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor);
    }
}
